package com.hsxc.cdz.trans.payment.gzhpay;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import net.sf.json.JSONObject;

public class WXUtil {
	/**
	 * 生成随机字符串
	 * 
	 * @return 随机字符串
	 */
	public static String getNonceStr() {
		Random random = new Random();
		return MD5Util.MD5Encode(String.valueOf(random.nextInt(10000)), "GBK");
	}

	/**
	 * 生成时间戳
	 * 
	 * @return 时间戳字符串
	 */
	public static String getTimeStamp() {
		return String.valueOf(System.currentTimeMillis() / 1000);
	}

	/**
	 * 微信支付签名算法sign，
	 * 
	 * @param characterEncoding
	 *            编码类型
	 * @param parameters
	 *            参数Map
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static String createSign(String characterEncoding, SortedMap<Object, Object> parameters, int type) {
		StringBuffer sb = new StringBuffer();
		Set<Entry<Object, Object>> es = parameters.entrySet();// 所有参与传参的参数按照accsii排序（升序）
		Iterator<Entry<Object, Object>> it = es.iterator();
		while (it.hasNext()) {
			Map.Entry entry = (Map.Entry) it.next();
			String k = (String) entry.getKey();
			Object v = entry.getValue();
			if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {
				sb.append(k + "=" + v + "&");
			}
		}
		// 确认key
		if (type == 1) {
			sb.append("key=" + ConstantUtil.APP_KEY_GZH);
		} else if (type == 4) {
			sb.append("key=" + ConstantUtil.APP_KEY_APP);
		}

		String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase();
		return sign;
	}

	/**
	 * 向指定 URL 发送POST方法的请求
	 * 
	 * @param url发送请求的
	 *            URL
	 * @param param
	 *            xml格式的字符串
	 * @return 请求的结果
	 */
	public static String sendPost(String url, String param) {
		PrintWriter out = null;
		BufferedReader in = null;
		String result = "";
		try {
			URL realUrl = new URL(url);
			// 打开和URL之间的连接
			URLConnection conn = realUrl.openConnection();
			// 设置通用的请求属性
			conn.setRequestProperty("accept", "*/*");
			conn.setRequestProperty("connection", "Keep-Alive");
			conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
			// 发送POST请求必须设置如下两行
			conn.setDoOutput(true);
			conn.setDoInput(true);
			// 获取URLConnection对象对应的输出流
			out = new PrintWriter(conn.getOutputStream());
			// 发送请求参数
			System.out.println("------发送PoST时------" + param.getBytes("UTF-8").toString());
			out.print(param.toString());
			// flush输出流的缓冲
			out.flush();
			// 定义BufferedReader输入流来读取URL的响应
			in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
			String line;
			while ((line = in.readLine()) != null) {
				result += line;
			}
		} catch (Exception e) {
			System.out.println("发送 POST 请求出现异常！" + e);
			e.printStackTrace();
		}
		// 使用finally块来关闭输出流、输入流
		finally {
			try {
				if (out != null) {
					out.close();
				}
				if (in != null) {
					in.close();
				}
			} catch (IOException ex) {
				ex.printStackTrace();
			}
		}
		return result;
	}

	/**
	 * 将请求得到的字符串结果转换成json对象
	 * 
	 * @param result
	 *            请求的结果，格式为xml
	 * @param request
	 * @return json对象
	 * @throws Exception
	 */
	public static JSONObject getH5PayStr(String result, int type) throws Exception {

		Map<String, String> map = parseXml(result);
		System.out.println("--map---" + map.toString());
		SortedMap<Object, Object> params = new TreeMap<Object, Object>();
		if (map.get("return_code").equals("SUCCESS") && map.get("result_code").equals("SUCCESS")) {
			if (type == 1) {
				// 公众号支付

				params.put("appId", ConstantUtil.APP_ID_GZH);// 那个Id是大写没错
				params.put("timeStamp", WXUtil.getTimeStamp());
				params.put("nonceStr", getNonceStr());
				params.put("package", "prepay_id=" + map.get("prepay_id"));
				params.put("signType", "MD5");
				params.put("paySign", createSign("utf-8", params, type));

			} else if (type == 4) {
				// 微信app支付
				params.put("appid", ConstantUtil.APP_ID_APP);
				params.put("partnerid", ConstantUtil.MCH_ID_APP);
				params.put("prepayid", map.get("prepay_id"));
				params.put("package", "Sign=WXPay");
				params.put("noncestr", getNonceStr());
				params.put("timestamp", WXUtil.getTimeStamp());
				params.put("sign", createSign("utf-8", params, type));
			}
		} else if (map.get("return_code").equals("SUCCESS") && map.get("result_code").equals("FAIL")) {
			
			params.put("errorcode", map.get("err_code"));
			params.put("message", map.get("err_code_des"));
		}

		JSONObject json = JSONObject.fromObject(params);

		return json;
	}

	public static Map<String, String> parseXml(String xml) throws Exception {
		Map<String, String> map = new HashMap<String, String>();

		Document document = DocumentHelper.parseText(xml);
		Element root = document.getRootElement();
		List<Element> elementList = root.elements();

		for (Element e : elementList)
			// if(e.getName().equals("packages"))
			map.put(e.getName(), e.getText());
		return map;
	}

	/**
	 * @author 李欣桦
	 * @date 2014-12-5下午2:32:05
	 * @Description：将请求参数转换为xml格式的string
	 * @param parameters
	 *            请求参数
	 * @return
	 */
	public static String getRequestXml(SortedMap<Object, Object> parameters) {
		StringBuffer sb = new StringBuffer();
		sb.append("<xml>");
		Set es = parameters.entrySet();
		Iterator it = es.iterator();
		while (it.hasNext()) {
			Map.Entry entry = (Map.Entry) it.next();
			String k = (String) entry.getKey();
			Object v = entry.getValue();
			// if ("attach".equalsIgnoreCase(k) || "body".equalsIgnoreCase(k) ||
			// "sign".equalsIgnoreCase(k)) {
			// sb.append("<" + k + ">" + "<![CDATA[" + v + "]]></" + k + ">");
			// } else {
			sb.append("<" + k + ">" + v + "</" + k + ">");
			// }
		}
		sb.append("</xml>");
		System.out.println("------下单xml-----" + sb.toString());
		return sb.toString();
	}

}